setMethod(f = "[",
  signature(x = "DotStack", i = "ANY", j = "missing"),
  definition = function (x, i) {
    if (missing(i)) {
      i <- seq_along(x@ok)
    }
    matrix(c(x@x[i], x@y[i]), nrow = length(i),
      dimnames = list(x@ok[i], c("x", "y")))
  })

setMethod(f = "show",
  signature = "DotStack",
  definition = function(object) {
    cat("\n XY Coordinates for dot radius ", object@h,
        "\n", sep = "")
    print(object[])
  })

setMethod(f = "print",
  signature = "DotStack",
  definition = function(x, ...) {
    cat("  Original data summary for ", x@name, ": \n",
        "Mean: ", mean(x@original, na.rm = TRUE),
        "  Range: [", min(x@original, na.rm = TRUE), ", ",
          max(x@original, na.rm = TRUE), "]",
        "  Length: ", length(x@original),
        "\n\n XY Coordinates for dot radius ", x@h,
        "\n", sep = "")
    print(x[])
  })

setMethod(f = "plot",
  signature = signature(x = "DotStack", y = "missing"),
  definition = function(x, y, yaxt = NULL, ylim = NULL, ...) {

    axis.switch <- FALSE
    if (missing(yaxt) & missing(ylim)) {
      axis.switch <- TRUE
      yaxt <- "n"
    }

    symbols(x = x, yaxt = yaxt, ylim = ylim, ...)

    if (axis.switch && min(x@y) >= 0) {
      at <- sort(unique(x@y))
      labels <- seq_along(at)
      axis(side = 2, at = at, labels = labels)
    }
  })


## foo <- function(object) {
##   xr <- range(object@x) + c(-object@h, object@h)
##   yr <- range(object@y) + c(-object@h, object@h)
##   ratio <- diff(yr)/diff(xr)
## #  if (ratio * 1.25 < 1) ratio <- ratio * 1.25

##   dev.new(width = 7, height = 7)
##   pushViewport(plotViewport(name = "plotRegion"))
##   pushViewport(viewport(x = unit(0.5, "npc"), y = unit(0.5, "npc"),
##     width = unit(1, "npc"),
##     height = unit(1, "npc"),
## #    default.units = "native",
##     xscale = xr,
##     yscale = xr, name = "plotRegion"))

##   grid.circle(x = unit(object@x, "native"),
##     y = unit(object@y, "native"),
##     r = unit(object@h, "native"),
##     name = "dataSymbols")
##   grid.rect()
##   grid.xaxis()
##   grid.yaxis()
## }

setMethod(f = "symbols",
  signature = "DotStack",
  definition = function(x, y, circles, squares, rectangles,
  stars, thermometers, boxplots, inches, add, fg, bg, xlab, ylab,
  main, xlim, ylim, ...) {
    if (missing(main)) main <- "Stacked Dot Plot"
    if (missing(xlab)) xlab <- x@name
    if (missing(ylab)) ylab <- "Frequency"

    if (identical(length(x@color), 1L)) {
      color <- x@color
    } else {
      color <- x@color[x@ok]
    }

    callNextMethod(x = x@x, y = x@y, circles = rep(x@h, length(x@x)),
      squares = squares, rectangles = rectangles, stars = stars,
      thermometers = thermometers, boxplots = boxplots, inches = FALSE,
      add = FALSE, fg = fg, bg = color, xlab = xlab, ylab = ylab,
      main = main, xlim = xlim, ylim = ylim, asp = 1, ...)
    })


setMethod(f = "[",
  signature = "VAObject",
  definition = function (x, i, j, ..., drop = TRUE) {
    newx <- cbind(logMAROS = x@logMAROS, logMAROD = x@logMAROD)

    callNextMethod(x = newx, i = i, j = j, ... = ..., drop = drop)
  })

setMethod(f = "show",
  signature = "VAObject",
  definition = function(object) {
    print(object[])
  })

setMethod(f = "print",
  signature(x = "VAObject"),
  definition = function(x, ...) {
    cat("Chart values and number of letters for interpolation \n\n")
    print(cbind(Values = x@chart.values,
      Nletters = x@chart.nletters), ...)
    cat("\n Zero value used for missing values \n")
    print(x@zero, ...)
    cat("\n Left and Right Eye logMAR Values \n")
    print(x[], ...)
  })

setMethod(f = "summary",
  signature = signature(object = "VAObject"),
  definition = function(object, weightbest = TRUE, w = c(.75, .25)) {
    output <- new("VASummaryObject", object)

    if (weightbest) {
      ## Thanks to Dr. David Winsemius for pmin/pmax
      output@logMAR.combined <-
        w[1] * pmin(object@logMAROS, object@logMAROD, na.rm = TRUE) +
        w[2] * pmax(object@logMAROS, object@logMAROD, na.rm = TRUE)
    } else {
      if (!identical(w[1], w[2])) {
        warning("Unequal weights applied to the left and right eyes")
      }
      output@logMAR.combined <-
        w[1] * object@logMAROS + w[2] * object@logMAROD
    }

    output@mean.logMAR <- mean(output@logMAR.combined, na.rm = TRUE)
    snell.denom <- logmar(x = output@logMAR.combined, 20, inverse = TRUE)
    output@snellen.combined <- paste("20/", round(snell.denom), sep = '')
    output@snellen.combined[is.na(snell.denom)] <- NA
    output@mean.snellen <- paste("20/",
      round(logmar(output@mean.logMAR, 20, inverse = TRUE)), sep = '')
    return(output)
  })

setMethod(f = "show",
  signature = "VASummaryObject",
  definition = function(object) {
    cat("Summary Information for logMAR Values", fill = TRUE)
    cat("------------------------------------- \n", fill = TRUE)
    print(summary(data.frame(
      "LeftEye" = object@logMAROS,
      "RightEye" = object@logMAROD,
      "Combined" = object@logMAR.combined)))
    cat("\n Mean Combined Snellen value:", object@mean.snellen, fill = TRUE)
  })

setMethod(f = "plot",
  signature = signature(x = "VASummaryObject", y = "missing"),
  definition = function(x, y, ...) {
    oldpar <- par(no.readonly = TRUE)
    on.exit(par(oldpar))
    layout(matrix(c(1, 2, 3, 3), 2, 2, byrow = TRUE))
    plot(x = x@logMAROS, y = x@logMAR.combined,
      xlab = "Left Eye logMAR", ylab = "Combined logMAR")
    plot(x = x@logMAROD, y = x@logMAR.combined,
      xlab = "Right Eye logMAR", ylab = "Combined logMAR")
    plot(StackedDots(data.frame(combined = x@logMAR.combined),
      map = link(x = combined, ...), plot = FALSE),
      xlab = "Combined logMAR Distribution")
  })

setMethod(f = "plot",
  signature = signature(x = "SEMSummary", y = "missing"),
  definition = function(x, y, ...) {
    corplot(x = x$sSigma, coverage = x$coverage, ...)
  })


